﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Neo4jRestSharp.Neo4jObjectServices;
using Neo4jRestSharp.Neo4jRestServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Neo4jRestSharp
{
	public class Node : PropertyContainer
    {
		private List<Relationship> relationsips;

		internal List<Relationship> InternalRelationships
		{
			get
			{
				if (relationsips == null)
				{
					relationsips = new List<Relationship>();
					relationsips.AddRange(nodeObjectServices.GetRelationshipsOnNode(this.Id, RelationshipDirection.All, Enumerable.Empty<string>()));
				}
				return relationsips;
			}
		}

		public void Delete()
		{
			if (this.InternalRelationships.Count > 0)
			{
				throw new Neo4jException("Node still has relationships");
			}
			nodeObjectServices.DeleteNode(this);
		}

		public Relationship CreateRelationshipTo(Node otherNode, Enum relationshipType)
		{
			Debug.Assert(nodeObjectServices != null);
			Relationship relationship = nodeObjectServices.CreateRelationship(this, relationshipType.ToString(), otherNode);
			this.relationsips = null;
			otherNode.relationsips = null;
			return relationship;
		}

		public IEnumerable<Relationship> GetRelationships()
		{
			foreach (var relationship in InternalRelationships)
			{
				yield return relationship;
			}
		}

		public IEnumerable<Relationship> GetRelationships(RelationshipDirection direction)
		{
			foreach (var relationship in InternalRelationships)
			{
				if (direction == RelationshipDirection.In && relationship.StartUri != this.selfUri)
				{
					yield return relationship;
				}
				else if (direction == RelationshipDirection.Out && relationship.StartUri == this.selfUri)
				{
					yield return relationship;
				}
				else if (direction == RelationshipDirection.All)
				{
					yield return relationship;
				}
			}
		}

		public IEnumerable<Relationship> GetRelationships(Enum relationshipType)
		{
			string reltype = relationshipType.ToString();
			foreach (var relationship in InternalRelationships)
			{
				if (relationship.Type == reltype)
				{
					yield return relationship;
				}
			}
		}

		public IEnumerable<Relationship> GetRelationships(RelationshipDirection direction, Enum relationshipType)
		{
			string reltype = relationshipType.ToString();
			foreach (var relationship in InternalRelationships)
			{
				if (relationship.Type == reltype)
				{
					if (direction == RelationshipDirection.In && relationship.StartUri == this.selfUri)
					{
						yield return relationship;
					}
					else if (direction == RelationshipDirection.Out && relationship.StartUri != this.selfUri)
					{
						yield return relationship;
					}
					else if (direction == RelationshipDirection.All)
					{
						yield return relationship;
					}
				}
			}
		}    	
    }
}
